
import { _decorator, Component, Node, ProgressBar, Label, Sprite, EventTouch } from 'cc';
import { CommandType, Message, MessageType } from '../framework/Message';
import { MessageBase } from '../framework/MessageBase';
import { MessageCenter } from '../framework/MessageCenter';
import { GameData } from '../GameData';
import { Map } from '../map/Map';
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = Hero
 * DateTime = Sat Feb 05 2022 15:07:38 GMT+0800 (China Standard Time)
 * Author = vvc_zeng
 * FileBasename = Hero.ts
 * FileBasenameNoExtension = Hero
 * URL = db://assets/script/player/Hero.ts
 * ManualUrl = https://docs.cocos.com/creator/3.3/manual/zh/
 *
 */

@ccclass('Hero')
export class Hero extends MessageBase {
    static Instance: Hero;

    private _type: number = -1;
    get type() {
        return this._type;
    }

    private _faction: number = -1;
    get faction() {
        return this._faction;
    }

    // 等级
    private _level: number;
    get level() {
        return this._level;
    }
    set level(v) {
        this._level = v;
        this.levelComp.string = this._level + '';
        for (let i = 0; i < 8; i++) {
            this.abilities[i] += this.growRate[i];
        }
        this.updateStat();
        this.hp = this.abilities[0];
        this.mp = this.abilities[1];
    }

    private _hp: number;
    get hp() {
        return this._hp;
    }
    set hp(v) {
        this._hp = Math.min(Math.max(0, v), this.abilities[0]);
        // 更新英雄血条
        this.hpComp.progress = this._hp / this.abilities[0];
    }

    private _mp: number;
    get mp() {
        return this._mp;
    }
    set mp(v) {
        this._mp = Math.min(Math.max(0, v), this.abilities[1]);
        // 更新英雄蓝条
        this.mpComp.progress = this._mp / this.abilities[1];
    }

    // 经验
    private _exp: number[];
    get exp(): number {
        return this._exp[0];
    }
    set exp(v: number) {
        this._exp[0] = v;
        if (this._exp[0] >= this._exp[1]) {
            this._exp[0] -= this._exp[1];
            this.level++;
            // 升级需要的经验增加
            this._exp[1] += this.level * 50;
        }
        // 更新经验条
        this.expComp.progress = this._exp[0] / this._exp[1];
    }

    // 金币
    private _gold: number;
    get gold() {
        return this._gold;
    }
    set gold(g) {
        this._gold = g;
        // 渲染金币
        this.goldComp.string = this._gold + '';
    }

    // 属性: 血 蓝 攻 防 命 运 速 暴 
    abilities: number[];
    // 英雄各属性成长率
    growRate: number[];

    // 其他组件
    hpComp: ProgressBar;
    mpComp: ProgressBar;
    expComp: ProgressBar;
    levelComp: Label;
    goldComp: Label;
    statComp: Label[];

    onLoad() {
        super.onLoad()
        Hero.Instance = this;

        this.statComp = <Label[]>this.node.getChildByName("Stat").getComponentsInChildren("cc.Label");
        this.hpComp = (<ProgressBar>this.node.getChildByName("HPBar").getComponent("cc.ProgressBar"));
        this.mpComp = (<ProgressBar>this.node.getChildByName("MPBar").getComponent("cc.ProgressBar"));
        this.expComp = (<ProgressBar>this.node.getChildByName("EXPBar").getComponent("cc.ProgressBar"));
        this.levelComp = (<Label>this.node.getChildByName("Level").getComponent("cc.Label"));
        this.goldComp = (<Label>this.node.getChildByName("Gold").getComponent("cc.Label"));
    }

    init() {
        this.messageType = MessageType.TYPE_HERO;
    }

    initData() {
        // 设初始值
        this.abilities = [60, 30, 28, 25, 15, 8, 8, 8];
        this.growRate = [8, 4, 3, 3, 2, 1, 1, 1];
        this.hp = this.abilities[0]
        this.mp = this.abilities[1]
        this._exp = [0, 65];
        this.exp = 0
        this.gold = 0
        this._level = 0
    }

    ReveiveMessage(message: Message) {
        super.ReveiveMessage(message);
        if (message.Command == CommandType.COM_UI_CHOICE_HERO) {
            // 初始化数据
            this.initData()
            // 选择英雄
            console.log("选择英雄职业", message.Content);
            this._type = Number(message.Content);
            // 计算角色初始属性成长
            for (let i = 0; i < GameData.Instance.heroData[this._type][0].length; i++) {
                const j = GameData.Instance.heroData[this._type][0][i];
                this.abilities[j] += GameData.Instance.heroData[this._type][1][i];
            }
        } else if (message.Command == CommandType.COM_UI_CHOICE_FACTION) {
            // 选择英雄
            console.log("选择英雄势力", message.Content);
            this._faction = Number(message.Content);
            // 势力初始属性成长率
            for (let i = 0; i < GameData.Instance.factionData[this._faction].g[0].length; i++) {
                const j = GameData.Instance.factionData[this._faction].g[0][i];
                this.growRate[j] += GameData.Instance.factionData[this._faction].g[1][i];
            }
        } else if (message.Command == CommandType.COM_HERO_INIT) {
            // 激活子节点
            this.showHeroInfo()
            // 激活父节点
            this.node.active = true;
        } else if (message.Command == CommandType.COM_HERO_HP) {
            this.hp += Number(message.Content);
        } else if (message.Command == CommandType.COM_HERO_MP) {
            this.mp += Number(message.Content);
        }
    }
    showHeroInfo() {
        // 激活每一个子节点
        this.node.children.forEach((e) => {
            e.active = true;
        })
        // 更换英雄头像
        let _n = <Sprite>this.node.getComponent("cc.Sprite")
        let _s = GameData.Instance.heroFrames[this._type];
        _n.spriteFrame = _s;
        // 更换英雄势力图片
        _n = <Sprite>this.node.getChildByName("Faction").getComponent("cc.Sprite");
        _s = GameData.Instance.factionFrames[this._faction];
        _n.spriteFrame = _s;
        // 更新非战斗状态下的八种属性
        this.updateStat();
    }
    // 更新八种属性的label，如果不传参数，就是显示正常的属性
    updateStat(stat?: number[]) {
        this.node.getChildByName("Stat").children.forEach(e => e.on(Node.EventType.TOUCH_END, this.showTips));
        let st = stat ? stat : this.abilities;
        // 渲染基本属性
        for (let i = 0; i < 8; i++) {
            (<Label>this.statComp[i]).string = st[i] + '';
        }
    }
    showTips(e: EventTouch) {
        // 点击8个子属性的位置时，在顶部消息栏，显示子属性代表的详情 map.showTips()
        MessageCenter.SendCustomMessage(MessageType.TYPE_MAP, CommandType.COM_MAP_SHOWTIPS, [(<Node>e.target).parent.name, (<Node>e.target).getSiblingIndex()]);
    }
}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.3/manual/zh/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.3/manual/zh/scripting/ccclass.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.3/manual/zh/scripting/life-cycle-callbacks.html
 */
